package Util;

import factory.HandlerFactory;
import interceprtor.InterceptorChain;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import servlet.Dispacther;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class HandlerInvoke {
    public Object Invoke(HandlerDefinition definition) throws IllegalAccessException, InstantiationException {
        //第一:创建对象 获取执行方法
        Object object = getObject(definition);
        //第二:模型数据绑定(给方法的参数赋值)
        Object[] conversion = Conversion(definition);
        //执行方法
        Object result = methodInvoke(definition, conversion, object);
        return result;
    }

    private Object methodInvoke(HandlerDefinition definition,Object[] parameValues,Object instance) throws IllegalAccessException {
        Method method = definition.getMethod();
        Object result=null;
        try {
            //第三:执行方法
            result = method.invoke(instance, parameValues);
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return result;
    }
    public Object getObject(HandlerDefinition definition) throws IllegalAccessException, InstantiationException {
        HttpServletRequest request = ActionContext.getContext().getRequest();
        HandlerFactory handler = (HandlerFactory) request.getServletContext().getAttribute(Dispacther.HANDLER);
        Object instance = handler.handler(definition);
        return instance;
    }
    //类型转换
    private Object[] Conversion(HandlerDefinition definition){
        Method method = definition.getMethod();
        //获取所有参数
        Parameter[] parameter = method.getParameters();
        //参数个数
        Object[] objects = new Object[method.getParameterCount()];

        for (int i=0;i<method.getParameterCount();i++){
            //获取参数
            Parameter parameter1 = parameter[i];
            //获取参数类型
            Class<?> type = parameter1.getType();
            //类型判断
            if (type.isPrimitive()||type.getName().startsWith("java.lang")||type.isArray()){
                bingSimple(parameter1,objects,i);
            }else {
                bingComplex(objects,i,type);
            }

        }
        return objects;

    }

    //简单类型转换
    private void bingSimple(Parameter parameter,Object[] paramters,int i){
        HttpServletRequest request =
                ActionContext.getContext().getRequest();
        //获取客户端传过来的值
        Object value=request.getParameter(parameter.getName());
        //进行基本类型转换
        paramters[i]=ConvertUtils.convert(value,parameter.getType());
    }

    //复杂类型转换
    private void bingComplex(Object[] objects,int i,Class<?> type){
        //可能传过来的是实体对象
        try {
            HttpServletRequest request = ActionContext.getContext().getRequest();
            objects[i] = type.newInstance();
            BeanUtils.populate(objects,request.getParameterMap());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }


}
